package fr.cpe.dp.projet2.controller;

import fr.cpe.dp.projet2.factory.GenericFactory;
import fr.cpe.dp.projet2.model.algo.IAlgorithm;
import fr.cpe.dp.projet2.model.music.IMusic;
import fr.cpe.dp.projet2.model.music.MusicType;
import fr.cpe.dp.projet2.model.musicBuilder.IMusicBuilder;
import fr.cpe.dp.projet2.model.musicPlayer.IMusicPlayer;
import fr.cpe.dp.projet2.model.musicPlayer.MusicPlayerObservable;
import fr.cpe.dp.projet2.model.shape.IShape;
import fr.cpe.dp.projet2.view.Step1MusicPlayerView;
import fr.cpe.dp.projet2.view.Step2MusicPlayerView;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.ControllerEventListener;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.ShortMessage;
import javax.swing.JOptionPane;

/**
 *
 * @author Benoit
 */
public class Step2MusicController implements ControllerEventListener {
    private Step1MusicController step1MusicController;
    private Step2MusicPlayerView musicPlayerView;
    private IMusicPlayer musicPlayer;
    private GenericFactory<IMusic> musicFactory;
    private Map<String,IMusicBuilder> mapMusicBuilders;
    private Map<String,MusicType> mapMusicTypes;
    private Map<String,IShape> mapShapeOptions;
    private Map<String,IAlgorithm> mapAlgorithmOptions;
    private IAlgorithm choosenAlgorithm;
    private IShape choosenShape;
    private boolean isPlaying;

    public Step2MusicController(Step2MusicPlayerView musicPlayerView, 
            GenericFactory<IMusic> musicFactory,IMusicPlayer musicPlayer,
            Map<String,IMusicBuilder> mapMusicBuilders,Map<String,MusicType> mapMusicTypes,
            Map<String,IShape> mapShapeOptions, Map<String,IAlgorithm> mapAlgorithmOptions) {
        
        this.step1MusicController = new Step1MusicController(
                new Step1MusicPlayerView(
                        mapMusicBuilders.keySet().toArray(new String[1]),
                        mapMusicTypes.keySet().toArray(new String[1])),
                musicFactory,
                musicPlayer, 
                mapMusicBuilders,
                mapMusicTypes
        );
        
        this.musicPlayerView = musicPlayerView;
        this.musicPlayer = musicPlayer;
        this.mapMusicBuilders = mapMusicBuilders;
        this.mapMusicTypes = mapMusicTypes;
        this.mapShapeOptions = mapShapeOptions;
        this.mapAlgorithmOptions = mapAlgorithmOptions;
        this.musicFactory = musicFactory;
        this.choosenAlgorithm = null;
        this.choosenShape = null;
        this.isPlaying = false;
            
        this.musicPlayerView.setVisible(true);
        
        this.bindListenners();
    }
    
    private void bindListenners() {
        ((MusicPlayerObservable) musicPlayer).addControllerEventListener(this);
        
        this.musicPlayerView.getBtnPlay().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                playButtonActionPerformed(e);
            }
        });
        
        this.musicPlayerView.getBtnPause().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                pauseButtonActionPerformed(e);
            }
        });
        
        this.musicPlayerView.getBtnStop().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                stopButtonActionPerformed(e);
            }
        });
    }
    
    @Override
    public void controlChange(ShortMessage event) {
        if(choosenAlgorithm != null && choosenShape != null) { 
            choosenAlgorithm.setMessage(event);
            musicPlayerView.setDrawPanelIsDrawAllowed(true);
            musicPlayerView.repaintDrawPanel();
        }
    }
    
    private void playButtonActionPerformed(ActionEvent e) {
        if(isPlaying) {
            try {
                musicPlayer.play();
                return;
            } catch (InvalidMidiDataException ex) {
                Logger.getLogger(Step2MusicController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        String shape = musicPlayerView.chooseShape();
        String algorithm = musicPlayerView.chooseAlgorithme();
        
        if(shape != null) {
            choosenShape = mapShapeOptions.get(shape);
        }
        if(algorithm != null) {
            choosenAlgorithm = mapAlgorithmOptions.get(algorithm);
        }
        
        if(choosenAlgorithm != null && choosenShape != null) {
            choosenAlgorithm.setMaxHeight(musicPlayerView.getDrawPanelHeight() / 2);
            choosenAlgorithm.setMaxWidth(musicPlayerView.getDrawPanelWidth() / 2);
            choosenAlgorithm.setMaxX(musicPlayerView.getDrawPanelWidth());
            choosenAlgorithm.setMaxY(musicPlayerView.getDrawPanelHeight());
            musicPlayerView.setChoosenAlgorithm(choosenAlgorithm);
            musicPlayerView.setChoosenShape(choosenShape);
            step1MusicController.play();
            isPlaying = true;
        } else {
            JOptionPane.showMessageDialog(null, "Vous n'avez pas choisi d'algorithm ou de forme");
        }
    }
    
    private void pauseButtonActionPerformed(ActionEvent e) {
        if(isPlaying) {
            musicPlayer.pause();
        }
    }
    
    private void stopButtonActionPerformed(ActionEvent e) {
        if(isPlaying) {
            musicPlayer.stop();
            isPlaying = false;
            musicPlayerView.repaintDrawPanel();
        }
    }
}
